﻿
using System;
using SoundEngine3.MIDI.Meta;

namespace ZquenceStudio3Host.DspPlugins.Synthesizers.Nodesizer.Engine
{
    public class ModuleInput : ModuleIO
    {
        private ModuleOutput mFromOutput;
        private double mVisualForce;

        public ModuleOutput FromOutput
        {
            get { return mFromOutput; }
            set
            {
                var fromOutput = mFromOutput;
                if (mFromOutput != value)
                {
                    lock (SoundEngine3.SoundEngine.SoundLocker)
                    {
                        mFromOutput = null;

                        // Disconnect old.
                        if (fromOutput != null)
                        {
                            // NOTE: Hal is.
                            if (fromOutput.ConnectedInputs.Contains(this))
                            {
                                fromOutput.RemoveInput(this);
                            }
                        }

                        // Notify disconnect.
                        RaiseOnDisconnected(fromOutput, this);

                        mFromOutput = value;

                        // Notify connected.
                        if (value != null)
                        {
                            RaiseOnConnected(mFromOutput, this);
                        }

                        if (value != null)
                        {
                            if (!value.ConnectedInputs.Contains(this))
                            {
                                value.AddInput(this);
                            }
                        }
                    }
                }
            }
        }

        public override double VisualForce
        {
            get
            {
                return mVisualForce;
            }
        }
        
        public override bool IsCircularConnected
        {
            get
            {
                // Loop until we find myself.
                return FindModuleViaInputs(Module, Module);
            }
        }

        public override bool IsConnected
        {
            get
            {
                return FromOutput != null;
            }
        }

        public ModuleInput(string shortName, string name, IOType type, BaseModule module)
            : base(shortName, name, type, module)
        {
        }
        
        public ModuleInput(string name, IOType type, BaseModule module)
            : base(name, type, module)
        {
        }

        public MidiStatus GetMidiState(int i)
        {
            if (FromOutput.AudioBuffer[i] == 0.0)
            {
                // Check this first because this state is very more common.
                return 0; // Invalid.
            }
            else if (FromOutput.AudioBuffer[i] == NOTE_ON)
            {
                mVisualForce = 1;
                return MidiStatus.NOTE_ON;
            }
            else if (FromOutput.AudioBuffer[i] == NOTE_OFF)
            {
                return MidiStatus.NOTE_OFF;
            }

            return 0; // Invalid.
        }

        public override string ToString()
        {
            return base.ToString() + " - Input: " + Name;
        }
    }
}
